Imports System.ComponentModel
Imports System.Configuration.Provider
Imports System.Web.Configuration
Imports System.Web.HttpContext
Imports System.Web.Security

<DataObject(True)> _
Public Class QuestionnaireODS

#Region "Initialize Part"

    Private Shared s_Initialized As Boolean
    Private Shared s_lock As New Object
    Private Shared s_Provider As QuestionnaireProvider
    Private Shared s_Providers As QuestionnaireProviderCollection

    Private Shared Sub Initialize()
        If Not s_Initialized Then
            'Avoid claiming lock if providers are already loaded
            If s_Provider Is Nothing Then
                SyncLock (s_lock)
                    'Get a reference to the <questionnaire> section
                    Dim section As QuestionnaireSection _
                        = CType(WebConfigurationManager.GetSection("DotNetPM.Business/questionnaire"), QuestionnaireSection)
                    'Load registered providers and point _provider to the default provider
                    s_Providers = New QuestionnaireProviderCollection()
                    ProvidersHelper.InstantiateProviders(section.Providers, s_Providers, GetType(QuestionnaireProvider))
                    s_Provider = s_Providers(section.DefaultProvider)
                    If s_Provider Is Nothing Then Throw New ProviderException("Unable to load default QuestionnaireProvider")
                    s_Initialized = True
                End SyncLock
            End If
        End If
    End Sub

    Public Shared ReadOnly Property Provider() As QuestionnaireProvider
        Get
            Initialize()
            Return s_Provider
        End Get
    End Property

#End Region


#Region "For Questonnaire"

    Public Shared Function CreateQuestionnaire( _
    ByVal studyId As String, _
    ByVal visitNumber As Byte, _
    ByVal instrumentId As String, _
    ByVal description As String) As Questionnaire
        If Current.User.IsInRole("QuestionnaireManagers") _
        OrElse Current.User.IsInRole("QuestionnaireAdmins") Then
            Return QuestionnaireODS.Provider.CreateQuestionnaire( _
                studyId, visitNumber, instrumentId, description, Current.User.Identity.Name)
        Else
            Throw New Exception("You have no right to create a questionnaire.")
        End If
    End Function

    Public Shared Sub DeleteQuestionnaire(ByVal original_ID As Integer)
        'Throw New Exception("The value passed to the delete method is " & original_ID)
        If Current.User.IsInRole("QuestionnaireAdmins") Then
            QuestionnaireODS.Provider.DeleteQuestionnaire(original_ID)
        Else
            Throw New Exception("You have no right to delete a questionnaire.")
        End If
    End Sub

    <DataObjectMethod(DataObjectMethodType.Select, True)> _
    Public Shared Function GetQuestionnaires( _
    ByVal studyId As String, _
    ByVal instrumentId As String) As DataView
        Return QuestionnaireODS.Provider.GetQuestionnaires(studyId, instrumentId)
    End Function

    <DataObjectMethod(DataObjectMethodType.Select, False)> _
    Public Shared Function GetQuestionnaire( _
    ByVal questionnaireId As Integer) As Questionnaire
        If questionnaireId = 0 Then
            Dim _quest As New Questionnaire(0)
            With _quest
                .CreatedDate = Now
                .CreatedBy = Current.User.Identity.Name
                .LastUpdated = .CreatedDate
                .LastUpdatedBy = .CreatedBy
            End With
            Return _quest
        End If
        Return QuestionnaireODS.Provider.GetQuestionnaire(questionnaireId)
    End Function

    Public Shared Sub UpdateQuestionnaire( _
    ByVal id As Integer, _
    ByVal studyId As String, _
    ByVal visitNumber As Byte, _
    ByVal instrumentId As String, _
    ByVal description As String, _
    ByVal original_id As Integer)
        If Current.User.IsInRole("QuestionnaireManagers") _
        OrElse Current.User.IsInRole("QuestionnaireAdmins") _
        OrElse IsEditable(id) Then
            If Security.IsEditable Then
                Dim _questionnaire As New Questionnaire(original_id)
                With _questionnaire
                    .StudyID = studyId
                    .VisitNumber = visitNumber
                    .InstrumentID = instrumentId
                    .Description = description
                End With
                QuestionnaireODS.Provider.UpdateQuestionnaire(_questionnaire)
            End If
        Else
            Throw New Exception("You have no right to edit this questionnaire.")
        End If
    End Sub


#End Region

#Region "For Permission"

    <DataObjectMethod(DataObjectMethodType.Select, False)> _
    Public Shared Function GetRoles( _
    ByVal questionnaireId As Integer, _
    ByVal isEditingPermission As Boolean, _
    ByVal showOnlyAssignedRoles As Boolean) As DataView
        Dim dtRoles As New DataTable
        dtRoles.Columns.Add("RoleName", GetType(String))
        dtRoles.Columns.Add("Allowed", GetType(Boolean))
        dtRoles.Columns.Add("Locked", GetType(Boolean))
        Dim AllowedRoles As New ArrayList
        Dim LockedAllowedRoles As New ArrayList
        Dim quest As Questionnaire = QuestionnaireODS.Provider.GetQuestionnaire(questionnaireId)
        If quest Is Nothing Then Return dtRoles.DefaultView
        LockedAllowedRoles.Add("QuestionnaireAdmins")
        If isEditingPermission Then
            If Not String.IsNullOrEmpty(quest.EdtingPermission) Then
                AllowedRoles.AddRange(quest.EdtingPermission.Split("|"))
            End If
        Else
            If Not String.IsNullOrEmpty(quest.EdtingPermission) Then
                LockedAllowedRoles.AddRange(quest.EdtingPermission.Split("|"))
            End If
            If Not String.IsNullOrEmpty(quest.TakingPermission) Then
                AllowedRoles.AddRange(quest.TakingPermission.Split("|"))
            End If
        End If
        Dim rolesArray As String() = Roles.GetAllRoles()
        For Each roleName As String In rolesArray
            Dim isAllowedRole As Boolean = AllowedRoles.Contains(roleName)
            Dim isLockedRole As Boolean = LockedAllowedRoles.Contains(roleName)
            If showOnlyAssignedRoles = False OrElse isAllowedRole OrElse isLockedRole Then
                Dim dr As DataRow = dtRoles.NewRow
                dr.Item(0) = roleName
                dr.Item(1) = isLockedRole OrElse isAllowedRole
                dr.Item(2) = isLockedRole
                dtRoles.Rows.Add(dr)
            End If
        Next
        Return dtRoles.DefaultView
    End Function

    Public Shared Sub UpdateQuestionnaireEditingPerm( _
    ByVal id As Integer, _
    ByVal perm As String)
        If Current.User.IsInRole("QuestionnaireAdmins") _
        OrElse IsEditable(id) Then
            QuestionnaireODS.Provider.UpdateQuestionnaireEditingPerm( _
                id, perm, Current.User.Identity.Name)
        Else
            Throw New Exception("You have no right to edit this permission.")
        End If
    End Sub

    Public Shared Sub UpdateQuestionnaireTakingPerm( _
    ByVal id As Integer, _
    ByVal perm As String)
        If Current.User.IsInRole("QuestionnaireManagers") _
        OrElse Current.User.IsInRole("QuestionnaireAdmins") _
        OrElse IsEditable(id) Then
            QuestionnaireODS.Provider.UpdateQuestionnaireTakingPerm( _
                id, perm, Current.User.Identity.Name)
        Else
            Throw New Exception("You have no right to edit this permission.")
        End If
    End Sub

#End Region

#Region "For Dropdown List"

    <DataObjectMethod(DataObjectMethodType.Select, False)> _
    Public Shared Function GetInstrumentIDsDDL() As DataView
        Return QuestionnaireODS.Provider.GetInstrumentIDs
    End Function

    <DataObjectMethod(DataObjectMethodType.Select, False)> _
    Public Shared Function GetStudyIDsDDL() As DataView
        Return QuestionnaireODS.Provider.GetStudyIDs
    End Function

#End Region

    Private Shared Function IsEditable(ByVal questionnaireId As Integer) As Boolean
        Dim perm As String = QuestionnaireODS.GetQuestionnaire(questionnaireId).EdtingPermission
        If String.IsNullOrEmpty(perm) Then
            Return False
        End If
        Dim perms As String() = perm.Split("|")
        For Each p As String In perms
            If Current.User.IsInRole(p) Then
                Return True
            End If
        Next
    End Function
End Class
